package net.csdn.business.service;

import com.alibaba.fastjson2.JSON;
import com.google.common.collect.Lists;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.common.domain.request.LabelOrgDto;
import net.csdn.business.common.domain.vo.OrgInfoVo;
import net.csdn.business.common.domain.vo.migrate.MigrateInfoLogVo;
import net.csdn.business.enums.MigrateEnum;
import net.csdn.business.facade.*;
import net.csdn.business.pojo.*;
import net.csdn.business.util.ListDivider;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Component
@Slf4j
public class MigrateSevice {

    @Autowired
    private UserFacade userFacade;
    @Autowired
    private LabelFacade labelFacade;
    @Autowired
    private MileStoneFacade mileStoneFacade;
    @Autowired
    private IssueFacade issueFacade;
    @Autowired
    private MigrateFacade migrateFacade;


    @Value("${grpc.atomgit.defaultChannel:gitee}")
    private String defaultChannel;


    //todo
    // user
    public Integer importAtomGitUser(List<AtomGitUser> userListList) throws Exception {
        return userFacade.registerForMigrate(userListList);
    }


    // group member
    public Integer importAtomGitGroupMember(List<AtomGitGroupMember> gitGroupMembers) throws Exception{
        return userFacade.importAtomGitGroupMember(gitGroupMembers);
    }

    // issue (comment save update)

    // milestone
    public Integer importMileStone(Long repoId,String repoGroupName,String repoName, List<AtomGitMileStone> mileStoneList){
        return mileStoneFacade.importMileStone(repoId,repoGroupName,repoName,mileStoneList);
    }

    // lable
    public Integer importLabels(List<String> groupPathList,List<AtomGitLabel> labelList){
        AtomicReference<Integer> succesNum = new AtomicReference<>(0);
        List<LabelOrgDto> labelOrgDtos = Lists.transform(labelList, i -> {
            LabelOrgDto labelOrgDto = new LabelOrgDto();
            labelOrgDto.setLabelColor("#"+i.getColor());
            labelOrgDto.setLabelName(i.getName());

            labelOrgDto.setOriginId(String.valueOf(i.getId()));
            long createdAt = i.getCreatedAt();
            if(createdAt!=0){
                labelOrgDto.setCreatedDate(new Date(createdAt*1000));
            }
            return labelOrgDto;
        });

        groupPathList.forEach((i)->{
            try {
                OrgInfoVo orgInfoVo = userFacade.getOrgInfo(i);
                if(ObjectUtils.isEmpty(orgInfoVo)){
                    log.error("error orgpath:{}",i);
                    return;
                }
            } catch (Exception e) {
                log.error("error orgpath:{},error:{}",i,e);
                return;
            }

            String adminUserId = userFacade.getOrgAdmin("", i);
            List<LabelOrgDto> labelOrgDtoList = labelOrgDtos.stream().map(label -> {
                label.setOrgPath(i);
                label.setCrrUserId(adminUserId);
                return label;
            }).collect(Collectors.toList());
            log.info("==== 导入标签,importLabel={}", JSON.toJSONString(labelOrgDtoList));
            //TODO 判断组织是否存在


            labelOrgDtoList.forEach(labelOrgDto -> {
                try {        //添加组织标签
                    labelFacade.addOrgLabel(labelOrgDto);
                    succesNum.getAndSet(succesNum.get() + 1);
                } catch (Exception e) {
                    log.error("addOrgLabel error:{},labelOrgDto:{}",e,new Gson().toJson(labelOrgDto));
                }
            });
        });
        return succesNum.get();
    }

    public Integer importAtomGitIssue(Long repoId,String repoGroupName, String repoName, List<AtomGitIssue> issueList) throws Exception{
        return issueFacade.importAtomGitIssue(repoId,repoGroupName,repoName,issueList);
    }


    public List<Long> checkAtomGitUser(AtomGitUserList list){
        List<AtomGitUser> userListList = list.getUserListList();
        List<Long> result = Lists.newArrayList();
        List<List<AtomGitUser>> lists = ListDivider.divideListWithGroupSize(userListList, 200);
        lists.forEach(i->{
            List<Long> transform = Lists.transform(i, ii -> {
                return ii.getId();
            });
            List<Long> ids = userFacade.checkAtomGitUser(transform, defaultChannel);
            if(!CollectionUtils.isEmpty(ids)){
                result.addAll(ids);
            }
        });
        return result;
    }
    public List<AtomGitGroupMember> checkAtomGitGroupMember(AtomGitGroupMemberList list){
        List<AtomGitGroupMember> memberList = list.getMemberListList();
        return userFacade.CheckAtomGitGroupMember(memberList);
    }

    public List<Long> checkAtomGitIssue(AtomGitIssueList list){
        //外层
        List<Long> resultIds = Lists.newArrayList();
        List<AtomGitIssue> issueList = list.getIssueListList();
        List<String> issueIds = Lists.transform(issueList, i -> {
            return String.valueOf(i.getId());
        });

        List<List<String>> lists = ListDivider.divideListWithGroupSize(issueIds, 200);
        lists.forEach(i->{
            List<Long> errorIds = checkByMigrateInfoLog(MigrateEnum.MigrateInfoTypeEnum.ISSUE.getCode(), i, list.getRepoGroupName(), String.valueOf(list.getRepoId()));
            if(!CollectionUtils.isEmpty(errorIds)) {
                resultIds.addAll(errorIds);
            }
        });

        if(!CollectionUtils.isEmpty(resultIds)) {
            return resultIds;
        }

        log.info("checkAtomGitIssue size same");
        //内层 检查 issue 下的评论数
        issueList.forEach(i->{
            List<AtomGitIssueComment> commentListList = i.getCommentListList();
            if(!CollectionUtils.isEmpty(commentListList)){
                List<String> commentIds = Lists.transform(commentListList, ii -> {
                    return String.valueOf(ii.getId());
                });
                List<Long> errIds = checkByMigrateInfoLog(MigrateEnum.MigrateInfoTypeEnum.COMMENT.getCode(), commentIds, list.getRepoGroupName(), String.valueOf(list.getRepoId()));
                if(!CollectionUtils.isEmpty(errIds)){
                    log.error("checkAtomGitIssue issueId:{},commentIds:{}",i.getId(),errIds);
                    resultIds.add(i.getId());
                }
            }
        });
            return resultIds;
    }

    public List<Long> checkAtomGitMilestone(AtomGitMileStoneList list){
        //外层
        List<AtomGitMileStone> listMiles = list.getMileStoneListList();
        List<String> ids = Lists.transform(listMiles, i -> {
            return String.valueOf(i.getId());
        });
        return checkByMigrateInfoLog(MigrateEnum.MigrateInfoTypeEnum.MILESTONE.getCode(), ids, list.getRepoGroupName(), String.valueOf(list.getRepoId()));
    }

   public List<Long> checkAtomGitLabel(AtomGitLabelList list){
        //外层
       List<Long> resultIds = Lists.newArrayList();
       List<String> groupNames = list.getGroupPathListList();
       List<AtomGitLabel> labelList = list.getLabelListList();
       List<String> ids = Lists.transform(labelList, i -> {
           return String.valueOf(i.getId());
       });
        groupNames.forEach(groupPath->{
            List<Long> errIds = checkByMigrateInfoLog(MigrateEnum.MigrateInfoTypeEnum.LABEL.getCode(), ids, groupPath, "");
            if(!CollectionUtils.isEmpty(errIds)){
                log.error("checkAtomGitLabel groupPath:{},errIds:{}",groupPath,errIds);
                resultIds.addAll(errIds);
            }
        });

       return resultIds.stream().distinct().collect(Collectors.toList());
   }

    public List<Long> checkByMigrateInfoLog(Integer type,List<String> ids,String repoGroupName,String repoId){
        List<MigrateInfoLogVo> migrateInfoLogVos = migrateFacade.queryLogs(type, ids, repoGroupName, repoId.toString());
        List<String> suscessIds = Lists.transform(migrateInfoLogVos, i -> {
            return i.getOriginId();
        });
        List<String> difference = ListDivider.getDifference(ids, suscessIds);
        if(CollectionUtils.isEmpty(difference)){
            return Lists.newArrayList();
        }
        return Lists.transform(difference,i->{return Long.valueOf(i);});
    }
}
